#ifndef __HEADER_BIG_NUM__
#define __HEADER_BIG_NUM__

#include "crypto/types.h"

#define NEG -1
#define POS 1
#define ILLEGAL 0
#define EQUAL 0

#define MAX_INT_VALUE_LENGTH 10
#define MAX_LONG_VALUE_LENGTH 20

struct bignum
{
    int len;
    int cap;
    int flag;
    byte *num;
};

typedef struct bignum BN;

BN *BNinit(uint len);
BN *BNbuild(byte *addr, uint len);
BN *BNbuildInt(int data);
BN *BNbuildInt64(int64 data);

void BNsetZero(BN *bn);
void BNsetInt(BN *bn, int data);
void BNsetInt64(BN *bn, int64 data);
void BNmod(BN *dividend, BN *quotient, BN *mod);
bool BNcompare(BN *res, BN *dst);

void BNcopy(BN *res, BN *dst);
void BNdestroy(BN *bn);

void BNadd(BN *augend, BN *addend, BN *sum);
void BNsub(BN *minuend, BN *subtrahend, BN *difference);
void BNmulti(BN *multiplicand, BN *multiplier, BN *product);
void BNhalf(BN *dividend, BN *quotient, bool *mod);
void BNpow(BN *base, BN *exponent, BN *power);
void BNpowerMod(BN *base, BN *exponent, BN *N, BN *mod);

#ifndef PRODUCT
void BNprint(BN *bn);
#endif

#endif
